home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
awe2-0_1.lha
/
awe2-0.1
/
Src
/
RCS
/
ThreadEventPairingHeap.cc,v
< prev
next >
Wrap
Text File
|
1988-10-12
|
10KB
|
386 lines
head 1.1;
access ;
symbols ;
locks grunwald:1.1; strict;
comment @@;
1.1
date 88.10.12.10.50.43; author grunwald; state Exp;
branches ;
next ;
desc
@@
1.1
log
@Initial revision
@
text
@// This may look like C code, but it is really -*- C++ -*-
/*
Copyright (C) 1988 Free Software Foundation
written by Dirk Grunwald (grunwald@@cs.uiuc.edu)
adapted for libg++ by Doug Lea (dl@@rocky.oswego.edu)
This file is part of GNU CC.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY. No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing. Refer to the GNU CC General Public
License for full details.
Everyone is granted permission to copy, modify and redistribute
GNU CC, but only under the conditions described in the
GNU CC General Public License. A copy of this license is
supposed to have been given to you along with GNU CC so you
can know your rights and responsibilities. It should be in a
file named COPYING. Among other things, the copyright notice
and this notice must be preserved on all copies.
*/
#include "stream.h"
#include "ThreadEventPairingHeap.h"
//
// This defines a Pairing Heap structure for a pointer data type.
//
// See ``The Pairing Heap: A New Form of Self-Adjusting Heap''
// Fredman, Segdewick et al,
// Algorithmica (1986) 1:111-129
//
// In particular, this implements the pairing heap using the circular
// list.
//
//
#define MIN_STORAGE_SIZE 8
// error handling
void default_ThreadEventPairingHeap_error_handler(char* msg)
{
cerr << "Fatal ThreadEventPairingHeap error. " << msg << "\n";
exit(1);
}
one_arg_error_handler_t ThreadEventPairingHeap_error_handler = default_ThreadEventPairingHeap_error_handler;
one_arg_error_handler_t set_ThreadEventPairingHeap_error_handler(one_arg_error_handler_t f)
{
one_arg_error_handler_t old = ThreadEventPairingHeap_error_handler;
ThreadEventPairingHeap_error_handler = f;
return old;
}
void ThreadEventPairingHeap::error(const char* msg)
{
(*ThreadEventPairingHeap_error_handler)(msg);
}
ThreadEventPairingHeap::ThreadEventPairingHeap(int length = 0)
{
freelist = ThreadEventPairingHeapIndex_NULL;
root = ThreadEventPairingHeapIndex_NULL;
allocatedSize = 0;
elements = 0;
make_room(length);
}
ThreadEventPairingHeapIndex ThreadEventPairingHeap::get_cell()
{
if (freelist == ThreadEventPairingHeapIndex_NULL)
make_room(0);
ThreadEventPairingHeapIndex cell = freelist;
storage[freelist].valid = 1;
freelist = storage[freelist].sibling;
elements++;
return(cell);
}
void ThreadEventPairingHeap::return_cell(ThreadEventPairingHeapIndex cell)
{
storage[cell].sibling = freelist;
storage[cell].valid = 0;
freelist = cell;
elements--;
}
void ThreadEventPairingHeap::make_room(int atLeast)
{
if (freelist == ThreadEventPairingHeapIndex_NULL)
{
if (allocatedSize > 0)
{
ThreadEventPairingHeapIndex newSize = (allocatedSize * 3) / 2;
ThreadEventPairingHeapRecord *newStorage = new ThreadEventPairingHeapRecord[newSize];
if (newStorage == 0)
error("make_room: out of space");
for (int i = 0; i < allocatedSize; ++i)
{
newStorage[i].item = storage[i].item;
newStorage[i].valid = storage[i].valid;
newStorage[i].sibling = storage[i].sibling;
newStorage[i].children = storage[i].children;
}
delete [allocatedSize] storage;
storage = newStorage;
for (i = allocatedSize; i < newSize; i++)
{
storage[i].sibling = i+1;
storage[i].valid = 0;
}
storage[newSize-1].sibling = ThreadEventPairingHeapIndex_NULL;
freelist = allocatedSize;
allocatedSize = newSize;
}
else
{
if (atLeast <= MIN_STORAGE_SIZE)
allocatedSize = MIN_STORAGE_SIZE;
else
allocatedSize = atLeast;
storage = new ThreadEventPairingHeapRecord[allocatedSize];
if (storage == 0)
error("make_room: out of space");
for (int i = 0; i < allocatedSize; i++)
{
storage[i].sibling = i+1;
storage[i].valid = 0;
}
storage[allocatedSize-1].sibling = ThreadEventPairingHeapIndex_NULL;
freelist = 0;
}
}
}
//
// make_child is not used since its
// code has now been directly encorporated into enq/del_front
//
// make_child takes two nodes and makes one the child of the other
// and returns the index of the new parent.
//
// We play fast and loose with the siblings field of a & b, although
// we maintain the siblings of the children.
//
ThreadEventPairingHeapIndex ThreadEventPairingHeap::make_child(ThreadEventPairingHeapIndex a,
ThreadEventPairingHeapIndex b)
{
ThreadEventPairingHeapIndex parent;
ThreadEventPairingHeapIndex child;
if (storage[a].item < storage[b].item)
{
parent = a; child = b;
}
else
{
parent = b; child = a;
}
//
// If the new parent has no children, simply add the new child.
// We assume that the child and the parent dont care about
// their *sibling* nodes
//
ThreadEventPairingHeapIndex popsKid = storage[parent].children;
if (popsKid == ThreadEventPairingHeapIndex_NULL)
{
storage[parent].children = child;
storage[child].sibling = child;
}
else
{
ThreadEventPairingHeapIndex temp = storage[popsKid].sibling;
storage[popsKid].sibling = child;
storage[child].sibling = temp;
storage[parent].children = child;
}
return(parent);
}
ThreadEventPairingHeapIndex ThreadEventPairingHeap::enq(ThreadEvent item)
{
ThreadEventPairingHeapIndex cell = get_cell();
storage[cell].item = item;
storage[cell].children = ThreadEventPairingHeapIndex_NULL;
storage[cell].sibling = ThreadEventPairingHeapIndex_NULL;
if (root == ThreadEventPairingHeapIndex_NULL)
return root = cell;
else
{
ThreadEventPairingHeapIndex parent;
ThreadEventPairingHeapIndex child;
if ( storage[root].item < storage[cell].item )
{
parent = root; child = cell;
}
else
{
parent = cell; child = root;
}
ThreadEventPairingHeapIndex popsKid = storage[parent].children;
if (popsKid == ThreadEventPairingHeapIndex_NULL)
{
storage[parent].children = child;
storage[child].sibling = child;
}
else
{
ThreadEventPairingHeapIndex temp = storage[popsKid].sibling;
storage[popsKid].sibling = child;
storage[child].sibling = temp;
storage[parent].children = child;
}
root = parent;
return cell;
}
}
//
// Item removal is the most complicated routine.
//
// We remove the root (should there be one) and then select a new
// root. The siblings of the root are in a circular list. We continue
// to pair elements in this list until there is a single element.
// This element will be the new root.
int ThreadEventPairingHeap::del_front()
{
int valid = FALSE;
do
{
if (root == ThreadEventPairingHeapIndex_NULL || elements <= 0)
return(0);
valid = storage[root].valid;
ThreadEventPairingHeapIndex child = storage[root].children;
return_cell(root);
if (child == ThreadEventPairingHeapIndex_NULL)
root = ThreadEventPairingHeapIndex_NULL;
else
{
while(storage[child].sibling != child)
{
// We have at least two kids, but we may only have
// two kids. So, oneChild != child, but it is possible
// that twoChild == child.
ThreadEventPairingHeapIndex oneChild = storage[child].sibling;
ThreadEventPairingHeapIndex twoChild = storage[oneChild].sibling;
// Remove the two from the sibling list
storage[child].sibling = storage[twoChild].sibling;
storage[oneChild].sibling = ThreadEventPairingHeapIndex_NULL;
storage[twoChild].sibling = ThreadEventPairingHeapIndex_NULL;
ThreadEventPairingHeapIndex bestChild;
ThreadEventPairingHeapIndex worstChild;
if (storage[oneChild].item < storage[twoChild].item)
{
bestChild = oneChild; worstChild = twoChild;
}
else
{
bestChild = twoChild; worstChild = oneChild;
}
ThreadEventPairingHeapIndex popsKid = storage[bestChild].children;
if (popsKid == ThreadEventPairingHeapIndex_NULL)
{
storage[bestChild].children = worstChild;
storage[worstChild].sibling = worstChild;
}
else
{
ThreadEventPairingHeapIndex temp = storage[popsKid].sibling;
storage[popsKid].sibling = worstChild;
storage[worstChild].sibling = temp;
storage[bestChild].children = worstChild;
}
if (twoChild == child)
{
// We have reduced the two to one, so we'll be exiting.
child = bestChild;
storage[child].sibling = child;
}
else
{
// We've removed two siblings, now we need to insert
// the better of the two
storage[bestChild].sibling = storage[child].sibling;
storage[child].sibling = bestChild;
child = storage[bestChild].sibling;
}
}
root = child;
}
} while ( !valid );
return 1;
}
int ThreadEventPairingHeap::del(ThreadEventPairingHeapIndex i)
{
if (storage[i].valid)
{
if (i == root)
del_front();
else
{
storage[i].valid = 0;
elements--;
}
return 1;
}
else
return 0;
}
ThreadEventPairingHeapTrav::ThreadEventPairingHeapTrav(ThreadEventPairingHeap& a)
{
h = &a;
for (current = 0; current < h->allocatedSize; current++)
if (h->storage[current].valid)
return;
current = ThreadEventPairingHeapIndex_NULL;
}
void ThreadEventPairingHeapTrav::del()
{
if (current == ThreadEventPairingHeapIndex_NULL)
h->error("del of null traverser");
h->del(current);
}
void ThreadEventPairingHeapTrav::advance()
{
if (current == ThreadEventPairingHeapIndex_NULL)
return;
for (current++; current < h->allocatedSize; current++)
if (h->storage[current].valid)
return;
current = ThreadEventPairingHeapIndex_NULL;
}
@